package chatController;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Mission: Model in the MVC pattern.
 * @author bazile gaye
 */

public class User {

    private String username;
    private InetAddress ipAddress;
    private Boolean stateSystem; // state = True si on est connecté, state = False on est déconnecté
    private HashMap users;
    private HashMap ipUsers;

    private Observer observerNI;
    private Observer observerGUI;

    /**
     * Constructor
     * @throws UnknownHostException if the application can't take the local ip-address.
     */
    public User() throws UnknownHostException{
            this.username = new String();
            this.ipAddress = InetAddress.getLocalHost();
            this.stateSystem = false;
            this.users = new  HashMap<InetAddress, String>();
            this.ipUsers = new  HashMap<String,InetAddress>();
            this.observerNI = null;
            this.observerGUI = null;
    }

    /**
     * Method use to change the view of the list, from a hashmap to a vector.
     * @return Vector usernames of connected remote users.
     */
    public Vector afficheListe(){
            //System.out.println("HashMap : "+this.users.toString());
            Vector vec = new Vector(this.users.values());
            return  vec;
    }

    /**
     * Add a new user in the user's HAshMap.
     * @param ipAd remote user's address.
     * @param username remote user's name.
     */
    protected void addUser(InetAddress ipAd, String username){
        if (!(users.containsKey(ipAd) && users.containsValue(username))){
            
            this.users.put(ipAd,username);
            this.ipUsers.put(username, ipAd);
           
            //System.out.println(users.toString());

            this.notifyChangeList();
          } 
    }
    
    /**
     * Remove a user who is deconnected from the hashmap.
     * @param ipAd address ip of the remote user.
     */
    protected void remove(InetAddress ipAd) {
            if (users.containsKey(ipAd)){
                    String username = (String) this.users.get(ipAd);
                    this.users.remove(ipAd);
                    this.ipUsers.remove(username);
                    this.notifyChangeList();

            }
    }

    /**
     * Remove all the users from the hashmap.
     */
    protected void removeAll(){
        this.users.clear();
        this.ipUsers.clear();
    }

    /**
     * Use to change the state of our system.
     * localUser connected: boo=true, 
     * localUSer deconnected: boo = false
     * @param boo current value for the current state of the system.
     */
    protected void changeState(Boolean boo){
            if (this.stateSystem != boo){
                    this.stateSystem = boo;
                    this.notifyAllObservers();
            }
    }

    /**
     * Get the state of the system : connected or deconnected.
     * @return stateSystem true if connected, false if deconnected.
     */
    public Boolean getStateSystem() {
            return stateSystem;
    }

    /**
     * This method notify the state changement at all the observers.
     * @param state true if connected, false if deconnected.
     */
    public void setStateSystem(Boolean state) {
            this.stateSystem = state;
            notifyAllObservers();
    }

    /**
     * Method use for the pattern Observer/observable.
     * It establishes a link between the observer and the observable.
     * @param observer 
     */
    public void attachNI(Observer observer){
            observerNI = observer;		
    }
    /**
     * Function use for the pattern Observer/observable.
     * It establishes a link between the observer and the observable.
     * @param observer 
     */
    public void attachGUI(Observer observer){
            observerGUI = observer;		
    }
    /**
     * This method notify the state changement at all the observers.
     */
    public void notifyAllObservers(){
            observerNI.updateState();
            observerGUI.updateState();
    }

    /**
     * Notify the observer associated to the ChatGui for a Changelment in the users'list.
     */
    public void notifyChangeList(){
            observerGUI.updateList();
    }

    /**
     * Fonction getting the name of the user who has this ip address.
     * @param ipad ip address of the remote user.
     * @return String : name of the remote user.
     */
    protected String getUsers(InetAddress ipad){
            return (String) this.users.get(ipad);
    }
    
    /**
     * Fonction getting the InetAddress of the user who has this name.
     * @param name name of the remote user.
     * @return InetAddress : ip-address of the remote user.
     */
    protected InetAddress getUsersIp(String name){
            return (InetAddress) this.ipUsers.get(name);
    }

    /**
     * Get the ipAddress of the local user.
     * @return InetAddress.
     */
    public InetAddress getIpAddress(){
            return this.ipAddress;
    }
    
    /**
     * Get the username of the local user.
     * @return String
     */
    public String getUsername() {
            return username;
    }

    /**
     * Update of the local user's name
     * @param username name given by the local user.
     */
    public void setUsername(String username) {
            this.username = username;
    }


}
